<template>
    <!-- 滚动区域开始 -->
    <view class="container">
        <z-paging
            ref="paging"
            v-model="groupNoticeList"
            :scroll-with-animation="true"
            :default-page-size="groupNoticeListParams.page_size"
            @query="handlerPullRefreshAndMore"
            @scroll="handleScroll"
        >

            <!-- 骨架屏区域开始 -->
            <uv-skeletons :loading="isSkeleton" :skeleton="skeletons"></uv-skeletons>
            <!-- 骨架屏区域结束 -->

            <template #top>
                <!-- 自定义导航区域开始 -->
                <TridentNavBar>
                    <template #left>
                        <!-- #ifdef MP-ALIPAY -->
                        <i class="iconfont icon-zuojiantou" style="font-size: 36rpx;font-weight: bold;"></i>
                        <!-- #else -->
                        <i class="iconfont icon-zuojiantou" style="font-size: 36rpx;"></i>
                        <!-- #endif -->
                    </template>
                    <template #default>群公告</template>
                    <template #right>
                        <span v-if="isAdmin" @click="handleShowPublish" style="border: 2rpx solid #fff;padding: 4rpx 20rpx;border-radius: 4rpx;">发布</span>
                    </template>
                </TridentNavBar>
                <!-- 自定义导航区域结束 -->
            </template>

            <!-- 列表区域开始 -->
            <view class="list-wrap">
                <view class="item" v-for="(item, index) in groupNoticeList" :key="index">
                    <!-- 头部区域开始 -->
                    <view class="header-box">
                        <view class="title">{{ item.title }}</view>
                        <view class="btn" v-if="isAdmin">
                            <button size="mini" type="warn" @click="handleDeleteNotice(item)">删除</button>
                        </view>
                    </view>

                    <!-- 内容区域开始 -->
                    <view class="content-box">
                        <view class="text-panel">{{ item.contents }}</view>
                        <view class="image-panel" v-if="item.image_url">
                            <view class="image-item" v-for="(value, index) in item.image_url.split(',')" :key="index">
                                <image
                                    :src="global.FILE_DOMAIN + value"
                                    @click="handleImagePreview(global.FILE_DOMAIN + value)"
                                />
                            </view>
                        </view>
                    </view>

                    <!-- 尾部区域开始 -->
                    <view class="footer-box">{{ item.create_time }}</view>
                </view>
            </view>
            <!-- 列表区域结束 -->

            <!-- 加载更多提示 -->
            <template #loadingMoreNoMore>
                <view :style=" safeAreaInsets && safeAreaInsets.bottom > 0 ? 'padding-bottom: ' + safeAreaInsets.bottom + 'px': ''" class="no-more-wrap" v-if="totalPage <= groupNoticeListParams.page && totalPage > 1">我也是有底线的！</view>
            </template>
        </z-paging>
    </view>
    <!-- 滚动区域结束 -->

    <!-- 发布群公告弹层开始 -->
    <uni-popup
        ref="popupRef"
        type="bottom"
        background-color="#fff"
        :mask-click="false"
    >
        <view class="popup-wrap">
            <!-- 标题区域开始 -->
            <view class="title-box">
                <text>发布公告</text>
                <i class="iconfont icon-guanbi" @click="popupRef.close()"></i>
            </view>
            <!-- 标题区域结束 -->

            <!-- 表单区域开始 -->
            <view class="input-box">
                <uni-forms
                    ref="formRef"
                    :rules="rules"
                    :modelValue="publishGroupNoticeParams"
                >

                    <!-- 标题 -->
                    <uni-forms-item label="标题" required name="title">
                        <uni-easyinput type="text" :primaryColor="global.THEME_COLOR" v-model="publishGroupNoticeParams.title" placeholder="请输入标题" />
                    </uni-forms-item>

                    <!-- 图片 -->
                    <uni-forms-item label="图片">
                        <uni-file-picker
                            v-model="uploaderList"
                            :limit="4"
                            :imageStyles="{width: 80,height: 80}"
                            disable-preview
                            fileMediatype="image"
                            @select="handleAfterRead"
                            @delete="handleDelete"
                        ></uni-file-picker>
                    </uni-forms-item>


                    <!-- 内容 -->
                    <uni-forms-item label="内容" required name="contents">
                        <uni-easyinput type="text" :primaryColor="global.THEME_COLOR" v-model="publishGroupNoticeParams.contents" placeholder="请输入内容" />
                    </uni-forms-item>

                    <!-- 内容 -->
                    <uni-forms-item label="备注">
                        <uni-easyinput type="text" :primaryColor="global.THEME_COLOR" v-model="publishGroupNoticeParams.note" placeholder="请输入备注" />
                    </uni-forms-item>
                </uni-forms>
            </view>
            <!-- 表单区域结束 -->

            <TridentButton @handleClick="handlePublish"/>
        </view>
    </uni-popup>
    <!-- 发布群公告弹层结束 -->

    <!-- 返回顶部 -->
    <TridentBackTop @backTop="backTop" :isShowBackTop="isShowBackTop"/>
</template>

<script lang="ts" setup>
import { reqGroupChatDetailAPI } from '@/apis/groupChat'
import { reqDeleteGroupNoticeAPI, reqGroupNoticeListAPI, reqPublishGroupNoticeAPI } from '@/apis/groupNotice'
import { useUserStore } from '@/stores'
import type { Member } from '@/types/groupChat'
import type { GroupNotice, GroupNoticeListParams, PublishGroupNoticeParams } from '@/types/groupNotice'
import { removeLastComma } from '@/utils/tools'
import { onShow } from '@dcloudio/uni-app'
import dayjs from 'dayjs'
import { inject, reactive, ref } from 'vue'

// --------------- 定义全局变量开始 ---------------
// 获取屏幕边界到安全区域距离
const { safeAreaInsets } = uni.getSystemInfoSync()

// 全局属性
const global: any = inject('global')

// 用户存储
const userStore = useUserStore()

// 获取页面参数
const query = defineProps({
    "gid": {
        type: String,
        default: '0'
    }
})
// --------------- 定义全局变量结束 ---------------



onShow(async() => {
    for (let index = 0; index < 7; index++) {
        skeletons.push(skeleton as never)
    }

    await getGroupChatInfo()
})



// --------------- 获取群聊信息开始 ---------------
// 是否管理员
const isAdmin = ref<boolean>(false)

// 获取群聊信息
const getGroupChatInfo = async () => {
    const result = await reqGroupChatDetailAPI(query.gid as never)
    result.data.member.forEach((item: Member) => {
        if (item.is_admin == 1 && item.uid == userStore.profile.user?.uid) {
            isAdmin.value = true
        }
    })
}
// --------------- 获取群聊信息结束 ---------------



// ------------下拉刷新 + 加载更多开始 ------------
const handlerPullRefreshAndMore = async (pageNo: number, pageSize: number) => {
    groupNoticeListParams.page = pageNo
    await getGroupNoticeList()
}
// ------------下拉刷新 + 加载更多结束 ------------


// ------------- 处理公告列表功能开始 -------------
const paging = ref()

// 公告列表参数
const groupNoticeListParams = reactive<GroupNoticeListParams>({
    gid: query.gid as never,
    page: 1,
    page_size: 10
})

// 公告列表
const groupNoticeList = ref<GroupNotice[]>([])

// 总条数
const total = ref<number>(0)

// 总页数
const totalPage = ref<number>(0)

// 获取消息列表
const getGroupNoticeList = async () => {
    if (groupNoticeListParams.page == 1) {
        isSkeleton.value = true
    }

    // 请求数据
    const result = await reqGroupNoticeListAPI(groupNoticeListParams)
    total.value = result.data.total
    totalPage.value = result.data.total_page
    paging.value.complete(result.data.group_notices)

    // 隐藏骨架
    isSkeleton.value = false
}
// ------------- 处理消息列表功能结束 -------------



// --------------- 处理图片预览开始 ---------------
const handleImagePreview = (image_url: string) => {
    uni.previewImage({
		urls: [image_url]
	})
}
// --------------- 处理图片预览结束 ---------------



// --------------- 处理发布公告开始 ---------------
const popupRef = ref()

const formRef = ref()

// 验证规则
const rules = {
    title: {
		rules: [{
			required: true,
			errorMessage: '标题不能为空'
		}]
	},
    contents: {
		rules: [{
			required: true,
			errorMessage: '内容不能为空'
		}]
	}
}

// 上传图片列表
const uploaderList = ref([])

// 临时图片列表
const tempImageList:any = ref([])

// 发布公告参数
const publishGroupNoticeParams = ref<PublishGroupNoticeParams>({
    gid: query.gid as never,
    title: '',
    contents: '',
    image_url: '',
    note: '',
    network: 'ws'
})

// 显示发布公告弹层
const handleShowPublish = () => {
    publishGroupNoticeParams.value.title = ''
    publishGroupNoticeParams.value.contents = ''
    publishGroupNoticeParams.value.image_url = ''
    publishGroupNoticeParams.value.note = ''
    tempImageList.value = []
    uploaderList.value = []
    popupRef.value.open('bottom')
}

// 发布
const handlePublish = () => {
    formRef.value.validate().then(async () => {
        let image_url = ''
        tempImageList.value.forEach((item: any) => {
            image_url += item.image_url + ','
        })
        // 去除最后一个逗号
        publishGroupNoticeParams.value.image_url = removeLastComma(image_url)
        
        await reqPublishGroupNoticeAPI(publishGroupNoticeParams.value)
        uni.showToast({
            title: '发布成功',
            duration: 1000
        })

        // 关闭弹层
        popupRef.value.close()

        groupNoticeList.value.unshift({
            id: 0,
            gid: publishGroupNoticeParams.value.gid,
            title: publishGroupNoticeParams.value.title,
            contents: publishGroupNoticeParams.value.contents,
            image_url: publishGroupNoticeParams.value.image_url,
            note: publishGroupNoticeParams.value.note + '' ,
            status: 1,
            create_time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
            update_time: ''
        })
    }).catch(() => {
	})
}
// --------------- 处理发布公告结束 ---------------



// --------------- 处理图片上传开始 ---------------
const handleAfterRead = async (e: any) => {
    console.log('e = ', e);

    const tempFile = e.tempFiles[0]
    
    // 图片类型限制
	const imageTypes = [
		'image/jpg',
		'image/jpeg',
		'image/png',
	]
	if (!imageTypes.includes(tempFile.file.type)) {
        uni.showToast({
            title: '图片类型要求：jpeg、jpg、png',
            duration: 1000,
            icon: 'none'
        })

		return false
	}

	// 图片大小限制 2M
	if (tempFile.size > 1024 * 1024 * 2) {
        uni.showToast({
            title: '图片大小不能超过2M',
            duration: 1000,
            icon: 'none'
        })

		return false
	}


    uni.showLoading({
        title: '图片上传中...',
        mask: true
    })

    // 上传图片到服务器
    uni.uploadFile({
        url: global.UPLOAD_FILE_API,
        filePath: tempFile.url,
        name: 'image',
        success: (uploadFileRes) => {
            uni.hideLoading()
            // 解析数据
            let result = JSON.parse(uploadFileRes.data)

            if (result.status_code == 200) {
                // 追加图片
                tempImageList.value.push({temp_file_path: tempFile.url, image_url: result.data.relative_url})
                uni.showToast({
                    title: '上传完成',
                    duration: 1000
                })
            } else {
                uni.showToast({
                    icon: 'none',
                    title: '上传失败',
                })
            }
        },
        fail: () => {
            uni.hideLoading()
            uni.showToast({
                icon: 'none',
                title: '服务器开小差啦!',
            })
        }
    })
}
// --------------- 处理图片上传结束 ---------------



// --------------- 处理删除图片开始 ---------------
const handleDelete = (e: any) => {
    const index = tempImageList.value.findIndex((item: any) => item.temp_file_path == e.tempFilePath)
    tempImageList.value.splice(index, 1)
}
// --------------- 处理删除图片结束 ---------------



// --------------- 处理删除公告开始 ---------------
const handleDeleteNotice = (item: GroupNotice) => {
    if (!isAdmin.value) {
        uni.showToast({
            title: '管理员才能删除公告',
            duration: 1000,
            icon: 'none'
        })

        return false
    }

    uni.showModal({
        content: '确定要删除公告吗?',
        confirmColor: global.THEME_COLOR,
        success: async (res) => {
            if (res.confirm) {
                await reqDeleteGroupNoticeAPI(item.id + '');

                // 删除
                const index = groupNoticeList.value.findIndex(value => value.id == item.id)
                groupNoticeList.value.splice(index, 1)
                
                uni.showToast({
                    title: '删除公告成功',
                    duration: 1000
                })
            }
        }
	})
}
// --------------- 处理删除公告结束 ---------------



// --------------- 返回顶部功能开始 ---------------
// 定义是否显示返回顶部
const isShowBackTop = ref(false)

// 返回顶部
const backTop = () => {
  paging.value.scrollToTop()
}

// 当滚动触发时，调用事件用于显示、隐藏返回顶部图标
const handleScroll = (e:any) => {
  isShowBackTop.value = e.detail.scrollTop > 300 ? true : false
}
// --------------- 返回顶部功能结束 ---------------



// --------------- 定义骨架变量开始 ---------------
// 定义是否显示骨架
const isSkeleton = ref(false)

// 定义骨架参数
const skeleton = reactive({
  type: 'flex',
  num: 1,
  style: 'margin: 20rpx;padding: 40rpx 30rpx 30rpx 25rpx;background-color: #fff;border-bottom: 2rpx solid #f6f6f6;justify-content: space-between;border-radius: 20rpx;',
  children: [
    // 标题区域
    {
      type: 'custom',
      num: 3,
      style: ['width: 140rpx;height: 45rpx;', 'width: 340rpx;height: 40rpx;','width: 440rpx;height: 40rpx;']
    },

    // 文本区域
    {
      type: 'custom',
      num: 1,
      style: ['width: 122rpx;height: 60rpx;']
    }
  ]
})
const skeletons = reactive([])
// --------------- 定义骨架变量结束 ---------------
</script>

<style scoped lang="scss">
.container {
    .list-wrap {
        padding: 0 20rpx 10rpx 20rpx;
        .item {
            background-color: #fff;
            padding: 30rpx;
            border-radius: 20rpx;
            margin-top: 10rpx;

            // 头部区域开始
            .header-box {
                font-size: 30rpx;
                display: flex;
                justify-content: space-between;
                align-items: center;
            }

            // 内容区域开始
            .content-box {
                margin: 20rpx 0px;
                border-top: 2rpx solid #e7e7e7;
                border-bottom: 2rpx solid #e7e7e7;
                padding: 20rpx 0px;
                .text-panel {
                    font-size: 26rpx;
                    line-height: 36rpx;
                    color:#858484;
                }
                .image-panel {
                    display: flex;
                    flex-wrap: wrap;
                    .image-item {
                        width: 160rpx;
                        height: 160rpx;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                        border: 2rpx solid #e7e7e7;
                        margin-right: 16rpx;
                        border-radius: 10rpx;
                        margin-top: 20rpx;
                        overflow: hidden;
                        &:nth-child(4n) {
                            margin-right: 0rpx;
                        }
                        image {
                            width: 140rpx;
                            height: 140rpx;
                        }
                    }
                }
            }

            // 尾部区域开始
            .footer-box {
                display: flex;
                justify-content: flex-end;
                color: #d3d2d2;
                font-size: 24rpx;
            }
        }
    }

    .no-more-wrap {
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 20rpx 0;
        color: #c3c0c0;
    }
}

// 弹层区域开始
.popup-wrap {
    padding-bottom: 40rpx;

    // 标题区域
    .title-box {
        display: flex;
        align-items: center;
        font-size: 32rpx;
        font-weight: bold;
        justify-content: center;
        height: 80rpx;
        color: $uni-color-primary;
        position: relative;
        border-bottom: 2rpx solid #e3e2e2;
        .icon-guanbi {
            font-size: 44rpx;
            color: #8e8c8c;
            position: absolute;
            right: 20rpx;
        }
    }

    // 输入框区域
    .input-box {
        padding: 30rpx 30rpx 0 20rpx;
    }
}
</style>